#include <QComboBox>
#include <QDateEdit>
#include <QLineEdit>
#include <QSpinBox>
#include "abstract-section-model.h"
#include "debug-helper.h"
#include "icon-store.h"
#include "standard-data-addition-dialog.h"
#include "ui_standard-data-addition-dialog.h"
#include "value-result.h"
#include "widget-helper.h"

StandardDataAdditionDialog::StandardDataAdditionDialog(QWidget *parent) :
    AbstractDataAdditionDialog(parent), ui(new Ui::StandardDataAdditionDialog)
{
    ui->setupUi(this);
    int iconSize = 16;
    m_okPixmap = IconStore::pixmap(IconStore::StatusOk, iconSize);
    m_errorPixmap = IconStore::pixmap(IconStore::StatusRejected, iconSize);
}

void StandardDataAdditionDialog::initialize()
{
    m_fieldNames = m_sectionModel->headerSectionsForAdding();
    QList<QAbstractItemDelegate*> delegates = m_sectionModel->delegatesForAdding();
    for (int i = 0; i < delegates.size(); i++)
        m_fieldValueWidgets.append(delegates.at(i)->createEditor(this, QStyleOptionViewItem(), QModelIndex()));
    Q_ASSERT(m_fieldNames.size() == m_fieldValueWidgets.size());

    createGui();
    setupAppearance();
}

void StandardDataAdditionDialog::setModel(AbstractSectionModel *model)
{
    m_sectionModel = model;
}

void StandardDataAdditionDialog::createGui()
{
    for (int i = 0; i < m_fieldNames.size(); i++)
    {
        QLabel* label = new QLabel(m_fieldNames.at(i), this);
        label->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
        ui->dataWidgetGridLayout->addWidget(label, i, 0);
        ui->dataWidgetGridLayout->addWidget(m_fieldValueWidgets.at(i), i, 1);
        m_fieldNameWidgets.append(label);
    }
}

void StandardDataAdditionDialog::setupAppearance()
{
    setWindowFlags((windowFlags() & ~Qt::WindowContextHelpButtonHint));
    setFixedHeight(minimumSizeHint().height());
    ui->stateIconLabel->clear();
    ui->stateLabel->clear();
    WidgetHelper::equalizeWidgetWidth(m_fieldNameWidgets);
    if (!m_fieldValueWidgets.isEmpty())
        m_fieldValueWidgets.first()->setFocus();
}

void StandardDataAdditionDialog::accept()
{
    validateInputData();
}

void StandardDataAdditionDialog::validateInputData()
{
    ui->stateIconLabel->startAnimation();
    repaint();
    m_inputData.clear();
    for (int i = 0; i < m_fieldValueWidgets.size(); i++)
    {
        QWidget* widget = m_fieldValueWidgets.at(i);
        QLineEdit* lineEdit = qobject_cast<QLineEdit*>(widget);
        if (lineEdit)
        {
            m_inputData << m_sectionModel->correctedValue(lineEdit->text(), i);
            continue;
        }

        QSpinBox* spinBox = qobject_cast<QSpinBox*>(widget);
        if (spinBox)
        {
            m_inputData << m_sectionModel->correctedValue(spinBox->value(), i);
            continue;
        }

        QDoubleSpinBox* doubleSpinBox = qobject_cast<QDoubleSpinBox*>(widget);
        if (doubleSpinBox)
        {
            m_inputData << m_sectionModel->correctedValue(doubleSpinBox->value(), i);
            continue;
        }

        QComboBox* comboBox = qobject_cast<QComboBox*>(widget);
        if (comboBox)
        {
            m_inputData << m_sectionModel->correctedValue(comboBox->itemData(comboBox->currentIndex()), i);
            continue;
        }

        QDateTimeEdit* dateTimeEdit = qobject_cast<QDateTimeEdit*>(widget);
        if (dateTimeEdit)
        {
            m_inputData << m_sectionModel->correctedValue(dateTimeEdit->dateTime(), i);
            continue;
        }

        fatalError(i);
    }
    ValueResult* result = m_sectionModel->canAddData(m_inputData);
    connect (result, &ValueResult::resultReady, this, &StandardDataAdditionDialog::finishValidateInputData);
}

void StandardDataAdditionDialog::finishValidateInputData (ValueResult* result)
{
    result->deleteLater();
    if (result->hasError())
    {
        ui->stateIconLabel->setPixmap(m_errorPixmap);
        ui->stateLabel->setText(result->error().text());
    }
    else
    {
        ui->stateIconLabel->setPixmap(m_okPixmap);
        ui->stateLabel->setText("Dane prawidłowe.");
        repaint();
        emit addDataRequested(m_inputData);
        QDialog::accept();
    }
}
